﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
using KinectDwa.Parsers;
using System.IO;
using KinectApplication;

namespace KinectDwa
{
    //new and glorious static class for kinect stuff
    public static class KinectHandler
    {
        private static KinectSensor kinect;
     
        private static bool kinectAppConflict;

        public static event EventHandler KinectReady;
        public static event EventHandler Failed;

        public static void Initialize()
        {
            KinectSensor.KinectSensors.StatusChanged += new System.EventHandler<StatusChangedEventArgs>(KinectSensors_StatusChanged);
            // show status for each sensor that is found now.

            foreach (KinectSensor k in KinectSensor.KinectSensors)
            {
                switch (k.Status)
                {
                    case KinectStatus.Disconnected:
                    case KinectStatus.NotPowered:
                        break;
                    default:
                        kinect = k;
                        InitializeKinectServices();
                        break;
                }
            }

            if (KinectSensor.KinectSensors.Count == 0)
            {
                if (Failed != null)
                {
                    Failed.Invoke(KinectStatus.Disconnected, null);
                }
            }
        }

        private static void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
        {
            if (e.Status == KinectStatus.Connected)
            {
            }
            else
            {
                if (Failed != null)
                {
                    Failed.Invoke(e.Status, null);
                }
            }
        }

        public static void UninitializeKinectService()
        {
            kinect.Stop();

            kinect.AllFramesReady -= KinectAllFramesReady;

            // Disable skeletonengine, as only one Kinect can have it enabled at a time.
            if (kinect.SkeletonStream != null)
            {
                kinect.SkeletonStream.Disable();
            }
        }

        private static void KinectAllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            // Have we already been "shut down" by the user of this viewer, 
            // or has the SkeletonStream been disabled since this event was posted?
            if ((kinect == null) || !((KinectSensor)sender).SkeletonStream.IsEnabled)
            {
                return;
            }

            SkeletonMouse.Parse((KinectSensor)sender, e);
        }

        public static void InitializeKinectServices()
        {
            // Centralized control of the formats for Color/Depth and enabling skeletalViewer
            kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
           
            TransformSmoothParameters paramss = new TransformSmoothParameters();


            //// Correction         amount of correction.  anging from 0.0 (no correction) to 1.0 (full correction). The default value is 0.5. 
            //paramss.Correction = 1F;

            //// JitterRadius       radius (in meters) for jitter reduction. The default value is 0.05 (5 cm). Any jitter less than this radius is aggressively smoothed out. 
            //paramss.JitterRadius = 0.05F;

            //// MaxDeviationRadius The maximum radius (in meters) that filtered positions can deviate from raw data. The default value is 0.04. 
            //paramss.MaxDeviationRadius = 0.07F;

            //// Prediction         number of predicted frames. 
            //paramss.Prediction = 0F;

            //// Smoothing          The amount of smoothing, ranging from 0.0 (no smoothing) to 1.0 (full smoothing). The default value is 0.5.
            //paramss.Smoothing = 0.5F;


            switch (Debugging.Smoothing)
            {
                case SmoothingParameters.Off:
                    break;
                case SmoothingParameters.Accurate:
                    paramss.Correction = 1F;
                    paramss.JitterRadius = 0.05F;
                    paramss.MaxDeviationRadius = 0.07F;
                    paramss.Prediction = 0F;
                    paramss.Smoothing = 0.5F;
                    break;
                case SmoothingParameters.Balanced:
                    paramss.Correction = 0;
                    paramss.JitterRadius = 0.15F;
                    paramss.MaxDeviationRadius = 0.15F;
                    paramss.Prediction = 0F;
                    paramss.Smoothing = 0.3F;
                    break;
                case SmoothingParameters.BalancedCorrection:
                    paramss.Correction = 1F;
                    paramss.JitterRadius = 0.15F;
                    paramss.MaxDeviationRadius = 0.15F;
                    paramss.Prediction = 0F;
                    paramss.Smoothing = 0.3F;
                    break;
                case SmoothingParameters.Smooth:
                    paramss.Smoothing = 0.75F;
                    paramss.Correction = 0.0F;
                    paramss.Prediction = 0.0F;
                    paramss.JitterRadius = 0.3F;
                    paramss.MaxDeviationRadius = 0.15F;
                    break;
                case SmoothingParameters.SmoothCorrection:
                    paramss.Smoothing = 0.5F;
                    paramss.Correction = 1.0F;
                    paramss.Prediction = 0.0F;
                    paramss.JitterRadius = 0.2F;
                    paramss.MaxDeviationRadius = 0.1F;
                    break;
                case SmoothingParameters.Default:
                    paramss.Smoothing = 0.75F;
                    paramss.Correction = 0.0F;
                    paramss.Prediction = 0.0F;
                    paramss.JitterRadius = 0.3F;
                    paramss.MaxDeviationRadius = 0.04F;
                    break;
            }

            kinect.SkeletonStream.Enable(paramss);

            kinect.AllFramesReady += KinectAllFramesReady;

            // Start streaming
            try
            {
                kinect.Start();

                if (KinectReady != null)
                {
                    KinectReady.Invoke(null, null);
                }
            }
            catch (IOException)
            {
            }
        }
    }
}
